﻿using System;
using System.Collections.Generic;
using System.Linq;
using WI.CandidateManager.Business.Objects.Helper;
using WI.CandidateManager.Common.Data.Entities;
using WI.CandidateManager.Common.Data.Enums;

namespace WI.CandidateManager.Business.Objects
{
	using WI.CandidateManager.Common.Data.Constants;
	using WI.CandidateManager.Common.Data.Enums;

	public class CandidateBO : UserBaseBO
	{
		#region Constructors

		public CandidateBO()
			: base()
		{
		}

		#endregion

		#region Methods

		/// <summary>
		/// Updates candidate record on specified in entity ID;
		/// </summary>
		/// <param name="candidate">
		/// The candidate.
		/// </param>
		public void UpdateCandidate(Candidate candidate)
		{
			var oldCandidate = DataContext.CandidateSet.Single(a => a.Id == candidate.Id);

			oldCandidate.FullName = candidate.FullName;
			oldCandidate.ShortName = candidate.ShortName;
			oldCandidate.Email = candidate.Email;
			oldCandidate.Phone = candidate.Phone;
			oldCandidate.Gender = candidate.Gender;

			DataContext.SaveChanges();
		}

		public Candidate CreateCandidate(Candidate candidate)
		{
			candidate = (Candidate)PrepareUser(candidate);
			candidate.Role = UserRole.Candidate;
			DataContext.CandidateSet.Add(candidate);
			DataContext.SaveChanges();
			return candidate;
		}

		public Candidate GetCandidateProfile()
		{
			var candidate = DataContext.CandidateSet.Single(m => m.Id == Session.User.Id);
			return candidate;
		}

        public List<ResultBase> GetResultList(TaskState state = TaskState.New)
        {
            var candidate = DataContext.CandidateSet.Single(m => m.Id == Session.User.Id);

            var list = DataContext.ResultBaseSet.Where(r => r.Candidate.Id == candidate.Id && r.Status == state && r.State == State.Active).ToList();

            return list;
        }

		public bool Update(string fullName, string passwordText,
			string shortName, string email, string phone, Gender gender)
		{
			try
			{
				Logger.Info(String.Format("Try update candidate profile.fullname: {0}, password: {1}, shortName: {2}, email: {3}, phone: {4}, gender: {5}",
					fullName, passwordText, shortName, email, phone, gender));

				var candidate = DataContext.CandidateSet.Single(c => c.Id == Session.User.Id);
				var entry = DataContext.Entry(candidate);

				if (!String.IsNullOrWhiteSpace(passwordText) && passwordText != InitialValueConstants.DefaultPassword)
				{
					CryptoHelper cryptedPassword = new CryptoHelper(passwordText.ToCharArray());
					candidate.Password = cryptedPassword.HashedPassword;
				}

				candidate.FullName = fullName;
				candidate.ShortName = shortName;
				candidate.Email = email;
				candidate.Phone = phone;
				candidate.Gender = gender;

				if (!entry.GetValidationResult().IsValid)
				{
					return false;
				}

				DataContext.SaveChanges();

				return true;
			}
			catch (Exception ex)
			{
				Logger.Error("Can't update candidate profile", ex);
				return false;
			}
		}

		/// <summary>
		/// Getting candidates list.
		/// </summary>
		/// <returns>List of candidates.</returns>
		public IEnumerable<Candidate> GetCandidates(long? candidateId = null, long? studyGroupId = null, State? candidateState = null)
		{
			return DataContext.CandidateSet
				.Where(c => (!candidateId.HasValue || c.Id == candidateId) &&
					(!studyGroupId.HasValue || c.StudyGroup.Any(g => g.Id == studyGroupId)) &&
					(!candidateState.HasValue || c.State == candidateState));
			
		}

		#endregion
	}
}
